// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;
using System.Collections.Generic;

namespace SnapObjects.Data
{
    internal class SimpleWriteFormater<TModel> : IDataWriteFormater<TModel>
    {
        protected readonly INodeWriter _writer;
        protected readonly IModelMeta _modelMeta;
        protected readonly ISet<string> _ignoreProperties;
        protected readonly string _modelName;

        public SimpleWriteFormater(INodeWriter writer, IModelMeta modelMeta,
            IEnumerable<string> ignoreProperties)
        {
            _writer = writer;
            _modelMeta = modelMeta;
            _ignoreProperties = new HashSet<string>(ignoreProperties);
            _modelName = typeof(TModel).Name;
        }

        public void WriteMetaColumns(int startProperty, int endProperty)
        {
            if (_modelMeta == null)
            {
                return;
            }

            if (startProperty > endProperty && endProperty >= 0)
            {
                throw new ArgumentException("The import interval is incorrect.");
            }

            var row = _writer.WriteAsObject(null);

            foreach (var item in _modelMeta.Properties)
            {
                if (_ignoreProperties.Contains(item.Name))
                {
                    continue;
                }

                if (item.Index >= startProperty && (item.Index <= endProperty || endProperty < 0))
                {
                    row.WriteAsValue(null).WriteValue(item.Name);
                }
            }

            row.WriteEndObject();
        }

        public void WriteName(string name)
        {
            throw new FormatException();
        }

        public override string ToString()
        {
            return _writer.ToString();
        }

        public void WriteEnd()
        {
            _writer.WriteEndArray();
        }

        public void WriteRows(IEnumerable<IModelEntry<TModel>> rows)
        {
            foreach (var row in rows)
            {
                var rowWriter = _writer.WriteAsObject(_modelName);

                foreach (var property in row.Properties)
                {
                    if (_ignoreProperties != null && _ignoreProperties.Contains(property))
                    {
                        continue;
                    }

                    var currentValue = row.GetCurrentValue(property);

                    rowWriter.WriteAsValue(property).WriteValue(currentValue);
                }

                rowWriter.WriteEndObject();
            }
        }

        public void WriteRow(IModelEntry<TModel> row)
        {
            var rowWriter = _writer.WriteAsObject(_modelName);

            foreach (var property in row.Properties)
            {
                if (_ignoreProperties != null && _ignoreProperties.Contains(property))
                {
                    continue;
                }

                var currentValue = row.GetCurrentValue(property);

                rowWriter.WriteAsValue(property).WriteValue(currentValue);
            }

            rowWriter.WriteEndObject();
        }
    }
}
